/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
#include <libxml/parser.h>
#include <libxml/tree.h>
#include "TestObject.h"
#include "World.h"

#include "owndebug.h"

CObject* CTestObject::LoadMLMA(CWorld *world, xmlNode *node)
{
  CObject *object=NULL;
  // Parameters for a Line.
  xmlChar *x = xmlGetProp(node, (xmlChar *) "x");
  xmlChar *y = xmlGetProp(node, (xmlChar *) "y");

  // Process.
  if (x && y) {
    object=new CTestObject(world,
                           atof((const char*)x),
                           atof((const char*)y) );
  } else {
    dPrint(1,"MLMA Error:Not enough parameters defined for testobject!");
  }

  // Cleanup (Always do this to clean out properties which were found)
  if (x) xmlFree(x);
  if (y) xmlFree(y);
  
  if (object)
    {
      world->InsertObject(object);
    }
  
  return object;
}

CTestObject::CTestObject(CWorld *World, float position_x, float position_y)
 :CObject(World,NULL),
  material1(DEFAULT_MATERIAL),
  material2(DEFAULT_MATERIAL),
  box1(1,1,1,this,this->SpaceID,0,&material1,false),
  box2(1.1,1.1,1.1,this,this->SpaceID,0,&material2,false),
  //sphere(1,this,this->SpaceID,0,&material2,false),
  //cylinder(0.3,1,this,this->SpaceID,0,&material2,false),
  motorSpeed(1.0)
{
  Parts.push_back(&box1);
  Parts.push_back(&box2);
  
  //place primitives // Note that Y = Z and Z = Y!!!
  dBodySetPosition(box1.BodyID,position_x+1.1,1.5,-position_y);
  dBodySetPosition(box2.BodyID,position_x,1.5,-position_y);
  
  //set some material properties
  material1.look.color[0]=1;
  material1.look.color[1]=1;
  material1.look.color[2]=0;
  material2.look.color[0]=0;
  material2.look.color[1]=1;
  material2.look.color[2]=0;
  //connect primitives with a hinge
  
  motor=dJointCreateHinge(WorldID,0);
  dJointAttach(motor,box1.BodyID,box2.BodyID);
  dJointSetHingeAxis(motor,1,0,0);
  dJointSetHingeAnchor(motor,position_x,1.5,-position_y);
  
  //start hinge motor
  dJointSetHingeParam(motor, dParamVel, motorSpeed);
  dJointSetHingeParam(motor, dParamFMax, 5000);
  
  //we want to know when box1 hits something
  box1.NotifyCollisions=true;
  
}
    
CTestObject::~CTestObject()
{
  
}

void CTestObject::Activate()
{
  //this function is called once after the object is created and added to the simulation 
  //when this is called, the world will be set up already and it is ready to create gimi connections
}

void CTestObject::Update(float StepSize)
{
  //this function is called on every simulation step
  
  //motor speed will change in course of time
  float t=SimWorld->GetSimulationTime();
  motorSpeed=t-floor(t/10);
  dJointSetHingeParam(motor, dParamVel, motorSpeed);
}
    
void CTestObject::OnCollision(CPrimitive *primitive, int numc, dContact *contacts, CPrimitive *primitive2)
{
  //this function is called when a child primitive of this object hits something
  //primitive's NotifyCollisions value must be set to true 
  
  //change other materials color
  material1.look.color[0]=1;
  material1.look.color[1]=!(bool)(material1.look.color[1]);
  material1.look.color[2]=0;
}
    
void CTestObject::Draw()
{
  for (ObjectsIter i=Children.begin();i!=Children.end();i++)
    {
      (*i)->Draw();
    }

  for (PrimitivesIter i=Parts.begin();i!=Parts.end();i++)
    {
      (*i)->Draw();
    }
}
